package zhoug.common.encrypt;

import android.content.Context;

import zhoug.logging.Logger;
import zhoug.common.utils.IOUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * assets目录下的加密文件解密工具
 *
 * @Author 35574
 * @Date 2021/10/29
 * @Description
 */
public class AssetsDecryptHelper {
    private static final String TAG = ">>>AssetsDecryptHelper";
    private IEncryptor iEncryptor;
    private String transformation;
    private String key;
    private String iv;

    public AssetsDecryptHelper(IEncryptor iEncryptor) {
        this.iEncryptor = iEncryptor;
    }

    public AssetsDecryptHelper(String transformation, String key, String iv) {
        this.transformation = transformation;
        this.key = key;
        this.iv = iv;
        iEncryptor = new AESHelper.Builder()
                .setIv(iv)
                .setKey(key)
                .setTransformation(transformation)
                .build();
    }

    /**
     * 解密assets下的文件
     *
     * @param context
     * @param assetsFolder          assets下需要解密的文件存储目录
     * @param suffix                需要解密的文件的后缀,为null时解密全部文件
     * @param destFolder            解密后的文件存储目录
     * @param destNameWithOutSuffix 解密后的文件命名规则:是否要去掉原文件的后缀(eg:原文件:baidu.cer.enpt去掉后缀后baidu.cer)
     */
    public void startDecrypt(Context context, String assetsFolder, String suffix, String destFolder, boolean destNameWithOutSuffix) {
        long startTime = System.currentTimeMillis();
        try {
            String[] list = context.getAssets().list(assetsFolder);
            if (!destFolder.endsWith("/")) {
                destFolder += "/";
            }
            if (list != null && list.length > 0) {
                for (String path : list) {
                    //baidu.cer.encrypt
                    if (suffix == null || path.endsWith(suffix)) {
                        //解密后的文件的名字
                        String destFileName = path;
                        if (destNameWithOutSuffix) {
                            int index = path.lastIndexOf(".");
                            if (index > 0) {
                                destFileName = path.substring(0, index);
                            }
                        }
                        final String assetPath = assetsFolder + "/" + path;
                        final String destPath = destFolder + destFileName;
                        startDecrypt(context, assetPath, destPath);
                    } else {
                        Logger.d(TAG, "跳过:" + path);
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            long endTime = System.currentTimeMillis();
            Logger.d(TAG, "耗时:" + (endTime - startTime));
        }

    }

    /**
     * 解密assets目录下的文件
     *
     * @param context
     * @param assetPath asset下的文件路径
     * @param destPath  解密后存储的文件路径
     */
    public void startDecrypt(Context context, String assetPath, String destPath) {
        Logger.d(TAG, "开始解密:" + assetPath);
        File destFile = new File(destPath);
        if (destFile.exists()) {
            Logger.d(TAG, "文件已存在");
            return;
        }
        if (!destFile.getParentFile().exists()) {
            destFile.getParentFile().mkdirs();
        }
        Logger.d(TAG, "解密后:" + destFile.getAbsolutePath());
        InputStream in = null;
        FileOutputStream fos = null;
        try {
            in = context.getAssets().open(assetPath);
            fos = new FileOutputStream(destFile);
            iEncryptor.decrypt(in, fos);
            Logger.d(TAG, "解密成功:");
        } catch (IOException e) {
            e.printStackTrace();
            Logger.d(TAG, "解密失败:" + e.getMessage());
        } finally {
            IOUtils.close(fos);
            IOUtils.close(in);
        }


    }

    public void test() {
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        for (int i = 1; i <= 5; i++) {
            final int c = i;
            executorService.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(c * 1000);
                        Logger.d(TAG, "run:任务执行:" + c);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        try {
            executorService.shutdown();
            if (!executorService.awaitTermination(3, TimeUnit.SECONDS)) {
                Logger.d(TAG, "超时:");
                executorService.shutdownNow();
            }
            Logger.d(TAG, "线程池已经关闭:");

        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

}
